<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */
namespace app\service\cdc\sync\account;

use app\enum\CdcEnum;
use app\model\mongo\MongoReportModel;
use app\model\mongo\MongoStatModel;
use app\model\mongo\MongoSyncModel;
use app\service\cdc\AccountService;
use app\service\cdc\sync\LogService;
use app\service\stat\daily\AccountService as DayAccountService;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

abstract class AccountLogService extends LogService
{
    /**
     * @var int 媒体ID
     */
    protected int $mediaId = 0;

    /**
     * 中间件模型.
     */
    protected ?MongoSyncModel $syncModel;

    /**
     * 基本信息模型.
     */
    protected ?MongoReportModel $recordModel;

    /**
     * 汇总信息模型.
     */
    protected ?MongoStatModel $statModel;

    /**
     * 初始化数据模型.
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function setModel(): bool
    {
        if (! $this->getStatModel()) {
            return false;
        }

        if (! $this->getRecordModel()) {
            return false;
        }

        return true;
    }

    /**
     * 删除当前日志.
     * @param MongoSyncModel $model 当前日志模型
     */
    public static function deleteLogByModel(MongoSyncModel $model): bool
    {
        return AccountService::deleteSyncLog($model, CdcEnum::LOG_DELETE_SELF);
    }

    /**
     * 删除指定账户素材日志.
     * @param MongoSyncModel $model 当前日志模型
     */
    public static function deleteLogByMaterialId(MongoSyncModel $model): bool
    {
        return AccountService::deleteSyncLog($model, CdcEnum::LOG_DELETE_MATERIAL);
    }

    /**
     * 新增日志.
     * @param MongoReportModel $model 记录表模型
     */
    public static function addLogByRecord(MongoReportModel $model): bool
    {
        // 账户信息
        $accountInfo = \app\service\client\AccountService::getAccountModel($model->getAttr('account_id'));
        // 账户端口信息
        $portInfo = (new DayAccountService())->getPort($model->getAttr('adv_id'));
        $statMonth = intval(mb_substr(strval($model->getAttr('stat_date')), 0, 6));
        $model->setAttrs([
            'account_type' => $accountInfo->getAttr('account_type') ?? 0,
            'stat_month' => $statMonth ?? 0,
            'product_id' => $portInfo['product_id'] ?? 0,
        ]);

        $obj = static::getModel();
        $field = [
            'client_id' => $model->getAttr('client_id'),
            'account_id' => $model->getAttr('account_id'),
            'stat_date' => $model->getAttr('stat_date'),
            'type' => $model->getAttr('type'),
            'user_id' => static::getUserIdByAdvId($model->getAttr('adv_id') ?? '') ?? '',
            'account_type' => $model->getAttr('account_type'),
            'media_id' => static::getMediaId(),
        ];
        return AccountService::addSyncLog($obj, $field);
    }

    /**
     * 删除日志.
     * @param MongoSyncModel $model 中间表模型
     * @param int $statDate 汇总表版本
     */
    public static function deleteLog(MongoSyncModel $model, int $statDate = 0): bool
    {
        if (! $statDate) {
            return self::deleteLogByModel($model);
        }
        return self::deleteLogByMaterialId($model);
    }

    /**
     * 获取信息.
     * @param array $where 条件
     * @return mixed
     */
    public static function getInfo(array $where = [])
    {
        return static::getModel()->where($where)->field(true)->find();
    }

    /**
     * 获取汇总数据模型.
     */
    public function getStatModel()
    {
        if (! in_array($this->syncModel->getAttr('type'), array_keys($this->statModelList))) {
            return self::setError('未知的统计类型');
        }

        $field = ['account_id'];
        $where = [];
        foreach ($field as $v) {
            $where[] = [$v, '=', $this->syncModel->getAttr($v)];
        }

        return $this->statModel = AccountService::getStatModel($this->mediaId, $this->syncModel->getAttr('type'), $where);
    }

    /**
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    public function getRecordModel()
    {
        if (! in_array($this->syncModel->getAttr('type'), array_keys($this->recordModelList))) {
            return self::setError('未知的统计类型');
        }

        $field = ['account_id', 'stat_date'];
        $where = [];
        foreach ($field as $v) {
            $where[] = [$v, '=', $this->syncModel->getAttr($v)];
        }

        $className = $this->recordModelList[$this->syncModel->getAttr('type')];
        $this->recordModel = (new $className())->where($where)->find();
        if (! $this->recordModel instanceof MongoReportModel) {
            $this->recordModel = new $className();
        }

        return $this->recordModel;
    }
}
